var app={

	/** 正在运行的子进程ID */
	runningPid:[],

	/**
	* app运行对话框,工具内的app运行有三种模式，console:使用控制台运行（没有界面），dialog:在工具主窗口内打开一个对话框通过iframe嵌入app页面，window:使用单独的窗口打开app页面。
	* 此处保存了app运行对话框的jquery引用，以便其他地方操作app对话框。
	*/
	appDialog:$("#dialogAppContainer"),

	/**
	* 初始化方法
	*/
	init:function(){
		this._initSearch();
		this._initMyAppList();
		this._initChoiceAppList();

		//监听主窗口关闭事件
		var win = nw.Window.get();
		win.on('close',function(){
			win.hide();
			if(app.runningPid.length>0){
				var pids = app.runningPid.join(' ');
				app.run("pkill -P "+pids); //杀死子进程
				app.run("kill "+pids);　//杀死当前进程
				app.runningPid = [];
			}
			setTimeout(function(){
				win.close(true);
			},2000)
		});
	},

	/**
	* 一个简单的alert对话框
	*/
	alert:function(title,msg){
		title=title||'信息';
		var dialog=$(`
				<div class="modal fade" tabindex="-1" role="dialog">
				  <div class="modal-dialog modal-sm" role="document">
				    <div class="modal-content">
				      <div class="modal-header">
				        <button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">&times;</span></button>
				        <h4 class="modal-title">${title}</h4>
				      </div>
				      <div class="modal-body">
				        ${msg}
				      </div>
				    </div>
				  </div>
				</div>
			`);
		dialog.modal('show');
	},

	/**
	* 在工具窗口顶部显示一个信息提示条，信息提示会在展示3秒后消失。
	*/
	tip:{

		_elShowAndRemoveDelay:function(el){
			$("body").prepend(el);
			setTimeout(function(){
				el.remove();
			},3000);
		},

		// 一般信息
		info:function(msg){
			this._elShowAndRemoveDelay($('<div class="alert alert-info navbar-fixed-top" role="alert">'
				+'<button type="button" class="close" data-dismiss="alert" aria-label="Close"><span aria-hidden="true">&times;</span></button>'
				+'<strong>【信息】</strong> '+msg+'</div>'));
		},
		
		// 成功信息
		success:function(msg){
			this._elShowAndRemoveDelay($('<div class="alert alert-success navbar-fixed-top" role="alert">'
				+'<button type="button" class="close" data-dismiss="alert" aria-label="Close"><span aria-hidden="true">&times;</span></button>'
				+'<strong>【成功】</strong> '+msg+'</div>'));
		},

		// 警告信息
		warning:function(msg){
			this._elShowAndRemoveDelay($('<div class="alert alert-warning navbar-fixed-top" role="alert">'
				+'<button type="button" class="close" data-dismiss="alert" aria-label="Close"><span aria-hidden="true">&times;</span></button>'
				+'<strong>【警告】</strong> '+msg+'</div>'));
		},

		// 危险信息
		danger:function(msg){
			this._elShowAndRemoveDelay($('<div class="alert alert-danger navbar-fixed-top" role="alert">'
				+'<button type="button" class="close" data-dismiss="alert" aria-label="Close"><span aria-hidden="true">&times;</span></button>'
				+'<strong>【危险】</strong> '+msg+'</div>'));
		}
	},

	/**
	*	创建UUID
	*/
	createUUID:function(){
		var d = new Date().getTime();
	    if (window.performance && typeof window.performance.now === "function") {
	        d += performance.now(); //use high-precision timer if available
	    }
	    var uuid = 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function (c) {
	        var r = (d + Math.random() * 16) % 16 | 0;
	        d = Math.floor(d / 16);
	        return (c == 'x' ? r : (r & 0x3 | 0x8)).toString(16);
	    });
	    return uuid;
	},

	/**
	* 默认程序执行结果处理器，执行程序时没有给出输出回调函数，默认会使用这个。
	*/
	defaultCmdHander:{
		onOut:function(data){
			console.log(data.toString('UTF-8'));
		},
		onErr:function(data){
			console.warn(data.toString('UTF-8'));
		},
		onError:function(err){
			console.error("【启动失败】->" + err);
		},
		onClose:function(code){
			console.info("【进程退出】->" + code);
		}
	},

	/**
	* 运行系统命令
	*/
	run:function(cmd,callback){
		if(typeof(cmd)==typeof('')&&cmd!=''){
			var spawn = require('child_process').spawn;
			callback=callback||this.defaultCmdHander;
			
			console.log('【执行命令】--> '+cmd);
			var subprocess=spawn('/bin/sh',['-c',cmd]);
			app.runningPid.push(subprocess.pid);
			var callback=callback||defaultCmdHander;

			subprocess.stdout.on('data',(data) => {
				var outHandler=callback.onOut||defaultCmdHander.onOut;
				outHandler.call(subprocess,data);
			});

			subprocess.stderr.on('data',(data) => {
				var errHandler=callback.onErr||defaultCmdHander.onErr;
				errHandler.call(subprocess,data);
			});

			subprocess.on('error',(err) => {
				var errorHandler=callback.onError||defaultCmdHander.onError;
				errorHandler.call(subprocess,err);
			});

			subprocess.on('close', (code) => {
				//删除已经结束的PID
				app.runningPid.splice(app.runningPid.indexOf(subprocess.pid),1);
				
				var closeHandler=callback.onClose||defaultCmdHander.onClose;
				closeHandler.call(subprocess,code);
			});
		}
	},

	/**
	* 使用root权限运行系统命令，首次运行对弹出密码输入对话框，用户可以选择保存密码（使用localStorage存储）。
	* 保存密码以后再使用root权限运行命令就不再提示输入密码，否则每次都会都会提示。
	*/
	runAsRoot:function(cmd,callback){
		var pwd=localStorage.getItem('user-account-password');
		var useRootRun=function(pwd){
			app.run('echo "'+pwd+'"|sudo -S '+cmd,callback);
		};

		if(typeof(pwd)!=typeof('')||pwd==''){
			var requirePwdDialog=$(`
					<div class="modal fade" tabindex="-1" role="dialog">
					  <div class="modal-dialog" role="document">
					    <div class="modal-content">
					      <div class="modal-header">
					        <button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">&times;</span></button>
					        <h4 class="modal-title">密码授权</h4>
					      </div>
					      <div class="modal-body">
					      	<div class="alert alert-info" role="alert">
							  <strong>【注意】</strong> 你当前执行的程序需要使用管理员权限运行，请输入密码完成授权！
							</div>
					        <form>
					        	<div class="form-group">
								   <label>用户密码</label>
								   <input name="userPasswordInput" type="password" class="form-control" placeholder="请输入密码" />
								</div>
								<div class="checkbox">
								    <label>
								      <input name="savePasswodBox" type="checkbox"> 保存密码
								    </label>
								</div>
					        </form
					      </div>
					      <div class="modal-footer">
					        <button name="cancelBtn" type="button" class="btn btn-default" data-dismiss="modal">取消</button>
					        <button name="confirmBtn" type="button" class="btn btn-primary">确定</button>
					      </div>
					    </div>
					  </div>
					</div>
				`);
			
			var hasAppRun=app.appDialog.is(":visible")?true:false;
			requirePwdDialog.find('button[name="confirmBtn"]').click(function(){
				var pwd=requirePwdDialog.find('input[name="userPasswordInput"]').val();
				if(requirePwdDialog.find('input[name="savePasswodBox"]').is(":checked")){
					localStorage.setItem('user-account-password',pwd);
				}

				useRootRun(pwd);
				
				requirePwdDialog.modal('hide');
				if(hasAppRun) app.appDialog.modal('show'); //恢复app窗口
			});

			if(hasAppRun) app.appDialog.modal('hide'); //如果有APP在运行先隐藏
			requirePwdDialog.modal('show');
		}else{
			useRootRun(pwd);
		}
	},

	/**
	* 初始化我的应用列表
	* 1.用户可通过添加应用对话框添加自己有的程序或者命令，后续可直接在工具界面点击运行。
	* 2.已添加的应用使用localStorage存储
	* 3.拖动应用到我的应用列表外即可删除应用
	*/
	_initMyAppList:function(){

		var getMyAppList=function(){
			var myAppList=localStorage.getItem('my-app-list');
			if(myAppList==null||myAppList==''){
				myAppList=[];

				//默认加一个开源客服应用，推广一下 ^_^
				var appId=app.createUUID();
				var appName="开源客服";
				var appIcon="";
				var appCmd="http://www.yu-lu.cn/open-customer/";
				var appType="window";
				myAppList.push({"id":appId,"name":appName,"cmd":appCmd,"icon":appIcon,"type":appType});
			}else{
				myAppList=$.parseJSON(myAppList);
			}
			return myAppList;
		};

		var renderMyAppList=function(){
			$("#my_app_list").html(template("my-app-list",{data:getMyAppList()}));
		};

		var setMyAppList=function(myAppList){
			localStorage.setItem('my-app-list',JSON.stringify(myAppList));
		    renderMyAppList();
		};

		renderMyAppList();

	    $("body").on("click","a.my-app",function(e){
	        var name=$(this).data('name');
			var cmd=$(this).data('cmd');
	        var type=$(this).data('type');
			var params=$(this).data("params");

	        if(type=='dialog'){
	            $("#dialogAppTitle").text(name);
	            $("#dialogAppContainer div.modal-body").html('<div class="embed-responsive embed-responsive-16by9">'
					+'<iframe src="'+cmd+'" class="embed-responsive-item"></iframe></div>');
				e.preventDefault();
	        }else if(type=='console'){
				app.run(cmd);
				e.preventDefault();
			}else if(type=='window'){
				if(params){
					window.open(cmd,null,params);
					e.preventDefault();
				}
			}
		});

		(function(){
			
			/**
			* 拖动删除
			*/

			$("body").on("dragstart","a.my-app",function(e){
		        var id=$(this).data('id');
		        e.originalEvent.dataTransfer.setData("id",id);
		    });

		    $("body").bind("dragover",function(e){
		        e.preventDefault();
		    });

		    $("body").bind("drop",function(e){
		        if(!$(e.target).is("#my_app_list")&&
		            $(e.target).parents("#my_app_list").length==0){
		            
		            var id=e.originalEvent.dataTransfer.getData("id");
		            var newMyAppList=[];
		            var myAppList=getMyAppList();
		            for(var i=0;i<myAppList.length;i++){
		                if(myAppList[i].id!=id){
		                    newMyAppList.push(myAppList[i]);
		                }
		            }

		            setMyAppList(newMyAppList);

		            e.preventDefault();
		        }
		    });
		})();

		(function(){
			
			/**
			* 添加应用对话框
			*/

			$("#add-app-link").click(function(){
				$("#addAppDlg form")[0].reset();
			});

			var finishBtn=$("#addAppDlg button[name='finishBtn']");
			finishBtn.click(function(){
				var appId=app.createUUID();
				var appName=$("#addAppDlg input[name='appName']").val();
				var appCmd=$("#addAppDlg input[name='cmdInput']").val();
				var appIcon=$("#addAppDlg input[name='appIcon']").val();
				var appType=$("#addAppDlg input[name='appType']:checked").val();

				if(appIcon!=''&&appIcon.startsWith('/')){
					appIcon="file://"+appIcon;
				}

				var myAppList=getMyAppList();
				myAppList.unshift({"id":appId,"name":appName,"cmd":appCmd,"icon":appIcon,"type":appType});
				setMyAppList(myAppList);
				$("#addAppDlg").modal('hide');
			});
		})();
	},

	_getChoiceAppList:function(){
		var fs=require('fs');
		var data=fs.readFileSync(process.cwd()+"/data/choiceApp.json");
		return JSON.parse(data);
	},

	/**
	* 初始化精选应用列表
	*/
	_initChoiceAppList:function(){
		
		$("#choice_app_list").html(template("choice-app-list",{data:app._getChoiceAppList()}));

		$("body").on("click","a.choice-app",function(e){
	        var name=$(this).data('name');
			var cmd=$(this).data('cmd');
			var type=$(this).data('type');
			var params=$(this).data("params");

	        if(type=='dialog'){
	            $("#dialogAppTitle").text(name);
	            $("#dialogAppContainer div.modal-body").html('<div class="embed-responsive embed-responsive-16by9">'
					+'<iframe src="'+cmd+'" class="embed-responsive-item"></iframe></div>');
				e.preventDefault();
	        }else if(type=='console'){
				app.exec(cmd);
				e.preventDefault();
			}else if(type=='window'){
				if(params){
					window.open(cmd,null,params);
					e.preventDefault();
				}
			}
		});
	},

	/**
	* 初始化搜索
	*/
	_initSearch:function(){
		
		var choiceAppList=app._getChoiceAppList();

		$("#searchBtn").click(function(){
	        var searchText=$("#searchInput").val();
	        if(searchText!=''){
	        	/**
	        	* 我的应用搜索处理，匹配的展示，不匹配的隐藏
	        	*/
	        	var searchTxtUpCase=searchText.toUpperCase();
	            $(".my-app").each(function(){
	                var name=$(this).data('name');
	                if(name.toUpperCase().indexOf(searchTxtUpCase)==-1){
	                    $(this).hide();
	                }else{
	                    $(this).show();
	                }
	            });

	           /**
	           * 精选应用搜索处理，使用匹配的重新渲染列表
	           */
	           var choiceAppResult=[];
	           for(var i=0;i<choiceAppList.length;i++){
	           		if(choiceAppList[i].name.toUpperCase().indexOf(searchTxtUpCase)!=-1){
	           			choiceAppResult.push(choiceAppList[i]);
	           		}
	           }
	           $("#choice_app_list").html(template("choice-app-list",{data:choiceAppResult}));
	        }
	    });

		/**
		* 搜索框为空时展示所有应用
		*/
	    $("#searchInput").change(function(){
	        if($(this).val()==''){
	            $(".my-app,.choice-app").show();
	            $("#choice_app_list").html(template("choice-app-list",{data:choiceAppList}));
	        }
	    });
	}
};	

app.init();
